package swu.cx.definelock

import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.View
import java.lang.StringBuilder

class NewLock:View {
    //提示用户
    var showTip:((String)->Unit)? = null
    //进行跳转
    var doJump:(()->Unit)? = null
    private var space = 0f
    //记录九宫格的宽度
    private var mWidth = 0
    //记录九个点
    private val dots = mutableListOf<Dot>()
    //记录点亮过的点
    private val selectedDots = mutableListOf<Dot>()
    //记录上一个点
    private var lastDot:Dot? = null
    //记录滑动路径
    private val dotPath = Path()
    //连线的画笔
    private val linePaint = Paint().apply {
        color = Color.BLACK
        style = Paint.Style.STROKE
        strokeWidth = 2f
    }
    //记录移动的终点
    private val endPoint = Point()
    //记录密码
    private val pwd = StringBuilder()
    //写死密码
    private val password = "12369"
    constructor(context: Context):super(context){}
    constructor(context: Context,attrs: AttributeSet):super(context,attrs){}
    constructor(context: Context,attrs: AttributeSet,style:Int):super(context,attrs,style){}

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        init()

    }

    override fun onDraw(canvas: Canvas?) {
        if (!endPoint.equals(0,0)){
            canvas?.drawLine(
                lastDot!!.cx,lastDot!!.cy,
                endPoint.x.toFloat(),endPoint.y.toFloat(),
                linePaint
            )
        }
        drawNineDots(canvas)
    }
    //绘制九个点
    private fun drawNineDots(canvas: Canvas?){
        canvas?.drawPath(dotPath,linePaint)
        for (dot in dots){
            canvas?.drawCircle(dot.cx,dot.cy,dot.radius,dot.dotPaint)
            canvas?.drawCircle(dot.cx,dot.cy,dot.radius-2f,dot.fillPaint)
            if (dot.isSelected){
                canvas?.drawCircle(dot.cx,dot.cy,dot.innerRadius,dot.innerCirclePaint)
            }
        }
    }
    private fun init(){
        mWidth = Math.min(width,height)
        var radius = mWidth/10f
        space = (mWidth-6*radius)/4
        var cx = (if(measuredWidth>measuredHeight) (measuredWidth-measuredHeight)/2f+space else space)+radius
        var cy = (if (measuredWidth>measuredHeight) space else (measuredHeight-measuredWidth)/2f+space)+radius
        for (row in 0..2){
            for (column in 0..2){
                Dot(cx+column*(2*radius+space),cy+row*(2*radius+space),radius,row*3+column+1).also {
                    dots.add(it)
                }
            }
        }
    }
    private fun highlightDot(dot: Dot){
        if(!dot.isSelected) {
            pwd.append(dot.tag)
        }
        dot.isSelected = true
        selectedDots.add(dot)
        lastDot = dot
        endPoint.set(0,0)
        invalidate()
    }
    override fun onTouchEvent(event: MotionEvent?): Boolean {
        val x = event?.x
        val y = event?.y
        when(event?.action){
            MotionEvent.ACTION_DOWN->{
                isContains(x,y).also {
                    if (it!=null){
                        dotPath.moveTo(it.cx,it.cy)
                            highlightDot(it)
                    }
                }
            }
            MotionEvent.ACTION_MOVE->{
                isContains(x,y).also {
                    if (it!=null){
                        if (lastDot==null){
                            //是第一个点则moveTo
                            dotPath.moveTo(it.cx,it.cy)
                        }else{
                            //不是第一个点则lineTo
                            dotPath.lineTo(it.cx,it.cy)
                        }
                        highlightDot(it)
                    }else{
                        if (lastDot!=null) {
                            endPoint.set(x!!.toInt(), y!!.toInt())
                            invalidate()
                        }
                    }
                }
            }
            MotionEvent.ACTION_UP->{
                if (pwd.toString()==password){
                    showTip?.let {
                        it("密码正确！！")
                    }
                    //密码正确即跳转
                    doJump?.let {
                        it()
                    }
                }else{
                    //提示用户密码错误
                    showTip?.let {
                        it("密码错误，请重新绘制！！")
                    }
                }
                reset()
            }
        }
        return true
    }
    private fun isContains(x:Float?,y:Float?):Dot?{
        for (dot in dots){
            dot.rect.contains(x!!.toInt(), y!!.toInt()).also {
                if (it){
                    return dot
                }
            }
        }
        return null
    }
    private fun reset(){
        for (dot in dots){
            dot.isSelected = false
        }
        pwd.clear()
        endPoint.set(0,0)
        lastDot = null
        dotPath.reset()
        invalidate()
    }
    class Dot(val cx:Float,val cy:Float,val radius:Float,val tag:Int) {
        var isSelected = false
        var innerRadius = 0f
        val rect = Rect()
        val dotPaint = Paint().apply {
            color = Color.BLACK
            style = Paint.Style.STROKE
            strokeWidth = 2f
        }

        val innerCirclePaint = Paint().apply {
            color = Color.BLACK
            style = Paint.Style.FILL
        }
        val fillPaint = Paint().apply {
            color = Color.WHITE
            style = Paint.Style.FILL
        }
        init {
            rect.left = (cx-radius).toInt()
            rect.top = (cy-radius).toInt()
            rect.right = (cx+radius).toInt()
            rect.bottom = (cy+radius).toInt()
            innerRadius = radius/2.8f
        }
    }
}